package com.xinyi.basic.thread

import android.os.*
import android.util.Printer
import com.xinyi.basic.app.AppContext
import com.xinyi.basic.utils.LogUtil

/**
 * @author 新一
 * @date 2023/9/19 9:39
 * @description 线程处理程器，封装了 Android 4.4 及以上版本中的 HandlerThread 和 Looper。
 * 可以用来处理耗时任务，避免阻塞 UI 线程。
 *
 *              A threading processor that encapsulates HandlerThread and Loper from Android 4.4 and above.
 * Can be used to handle time-consuming tasks and avoid blocking the UI thread.
 */
public class ThreadHandler private constructor(looper: Looper, callback: Callback?) : Handler(looper, callback) {

    constructor(looper: Looper) : this(looper, null)

    companion object {

        private val NAME = ThreadHandler::class.java.simpleName

        /**
         * 创建一个带有指定回调和打印机(Printer)的 ThreadHandler 对象。
         *
         * @param callback 回调对象，用于处理消息
         * @param printer 打印机对象，用于记录消息日志
         * @param name 线程名，默认为常量 NAME
         * @return ThreadHandler 对象
         */
        fun createHandler(callback: Callback?, printer: Printer?, name: String = NAME): ThreadHandler {
            val mThread = HandlerThread(name)
            mThread.start()
            mThread.looper.setMessageLogging(printer)
            return ThreadHandler(mThread.looper, callback)
        }

        fun createHandler(callback: Callback?, name: String = NAME): ThreadHandler {
            val mThread = HandlerThread(name)
            mThread.start()
            return ThreadHandler(mThread.looper, callback)
        }

        fun createHandler(name: String = NAME): ThreadHandler {
            val mThread = HandlerThread(name)
            mThread.start()
            return ThreadHandler(mThread.looper)
        }
    }

    // UI 线程的 Handler 和 Thread 对象
    // The Handler and Thread objects for the UI thread
    private var mUIHandler: Handler? = Handler(Looper.getMainLooper())
    private var mUiThread: Thread? = mUIHandler?.looper?.thread

    // 工作线程的 ID
    // The ID of the worker thread
    private var mWorkerThreadID: Long = -1

    init {
        // 获取工作线程的 ID
        // Gets the ID of the worker thread
        mWorkerThreadID = looper.thread.id
    }

    /**
     * 退出工作线程
     *
     * Quit the work thread.
     */
    fun quit() {
        try {
            looper.quitSafely()
            removeCallbacksAndMessages(null)
            mUIHandler?.removeCallbacksAndMessages(null)
            mUIHandler = null
            mUiThread = null
        } catch (ex: Exception) {
            ex.printStackTrace()
        }
    }

    /**
     * 在 UI 线程中运行 Runnable 的助手方法
     *
     * A helper method that runs a Runnable on the UI thread.
     *
     * @param task 要执行的任务
     *             The task to be executed.
     */
    fun runOnUiThread(task: Runnable) {
        runOnUiThread(task, 0L)
    }

    /**
     * 在 UI 线程中运行 Runnable 的方法，支持延迟执行
     *
     * Method to run a Runnable in the UI thread, with support for delayed execution.
     *
     * @param task 要执行的任务
     *             The task to be executed.
     * @param duration 延迟执行的时间（毫秒）
     *                 The time (in milliseconds) to delay execution. Default value is 0, which means execute immediately.
     */
    fun runOnUiThread(task: Runnable?, duration: Long) {
        task ?: return
        mUIHandler?.removeCallbacks(task)
        if (duration > 0 || Thread.currentThread() !== mUiThread) {
            mUIHandler?.postDelayed(task, duration)
        } else {
            try {
                task.run()
            } catch (e: Exception) {
                LogUtil.e(e)
            }
        }
    }

    /**
     * 如果在 UI 线程上等待执行的指定 Runnable 存在，则移除其执行等待
     *
     * Removes the executing wait for the specified Runnable if it is waiting to be executed on the UI thread.
     *
     * @param task 要移除等待的任务
     *             The task to be removed from waiting.
     */
    fun removeFromUiThread(task: Runnable) {
        mUIHandler?.removeCallbacks(task)
    }

    /**
     * 执行在工作线程上指定的 Runnable，如果存在未执行的相同 Runnable 则被取消(仅执行随后指定的任务)
     *
     * Executes the specified Runnable on the worker thread.
     * If there is an identical Runnable that has not been executed yet,
     * it will be canceled (only the subsequently specified task will be executed).
     *
     * @param task 要执行的任务
     *             The task to be executed.
     */
    @Synchronized
    fun queueEvent(task: Runnable) {
        queueEvent(task, 0L)
    }

    /**
     * 执行在工作线程上指定的 Runnable，如果存在未执行的相同 Runnable 则被取消(仅执行随后指定的任务)
     *
     * Executes the specified Runnable on the worker thread.
     * If there is an identical Runnable that has not been executed yet,
     * it will be canceled (only the subsequently specified task will be executed).
     *
     * @param task 要执行的任务
     *             The task to be executed.
     * @param delayMillis 延迟执行的时间（毫秒）
     *                    The time (in milliseconds) to delay execution. Default value is 0, which means execute immediately.
     */
    @Synchronized
    fun queueEvent(task: Runnable, delayMillis: Long) {
        if (Thread.currentThread().id != AppContext.mMainContext.mainLooper.thread.id && Looper.myLooper() == null) {
            Looper.prepare()
        }
        try {
            removeCallbacks(task)
            when {
                delayMillis > 0 -> postDelayed(task, delayMillis)
                mWorkerThreadID == Thread.currentThread().id -> task.run()
                else -> post(task)
            }
        } catch (e: Exception) {
            LogUtil.d("Join queue execution exception（加入队列执行异常）：${e.printStackTrace()}")
        }
    }

    /**
     * 如果在工作线程上预定执行，取消指定的 Runnable
     *
     * Cancels the specified Runnable if it is scheduled for execution on the worker thread.
     *
     * @param task 要取消执行的任务
     *             The task to be canceled.
     */
    @Synchronized
    fun removeEvent(task: Runnable) {
        try {
            removeCallbacks(task)
        } catch (e: Exception) {
            e.printStackTrace()
            LogUtil.e("Removes the specified task exception from the queue（从队列中移除指定任务异常）：${e.message}")
        }
    }

    /**
     * 移除工作线程消息队列中的所有任务和消息
     *
     * Removes all tasks and messages in the worker thread message queue.
     */
    @Synchronized
    fun removeCallbacksAndMessages() {
        try {
            removeCallbacksAndMessages(null)
        } catch (e: Exception) {
            e.printStackTrace()
            LogUtil.e("Remove callbacks and message exceptions（删除回调和消息异常）：${e.message}")
        }
    }

    /**
     * 发送线程消息
     *
     * Sends a message to the worker thread message queue.
     *
     * @param msg 要发送的消息对象
     *            The message object to be sent.
     */
    @Synchronized
    fun sendThreadMessage(msg: Message) {
        sendThreadMessageDelayed(msg, 0L)
    }

    /**
     * 发送线程消息/延迟
     *
     * Sends a message to the worker thread message queue with optional delay.
     *
     * @param msg 要发送的消息对象
     *            The message object to be sent.
     * @param delayMillis 延迟执行的时间（毫秒）
     *                    The time (in milliseconds) to delay execution. Default value is 0, which means execute immediately.
     */
    @Synchronized
    fun sendThreadMessageDelayed(msg: Message, delayMillis: Long) {
        try {
            sendMessageDelayed(msg, delayMillis)
        } catch (e: Exception) {
            e.printStackTrace()
            LogUtil.e("Send message exception（发送消息异常）：${e.message}")
        }
    }
}